package com.ipzoe.app.controller;


import cn.hutool.core.collection.CollUtil;
import cn.hutool.core.date.DateUtil;
import cn.hutool.core.lang.Validator;
import cn.hutool.core.util.StrUtil;
import com.alibaba.fastjson.JSON;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.google.common.collect.Maps;
import com.ipzoe.act.model.SignedActivityBO;
import com.ipzoe.act.service.IActivityService;
import com.ipzoe.app.convert.ActivityConvert;
import com.ipzoe.app.convert.MemberRechargePackageConvert;
import com.ipzoe.app.convert.OrderConvert;
import com.ipzoe.app.core.annotation.Login;
import com.ipzoe.app.core.constants.AppConstants;
import com.ipzoe.app.dto.*;
import com.ipzoe.common.captcha.CaptchaCode;
import com.ipzoe.common.captcha.CaptchaCodeManager;
import com.ipzoe.common.core.controller.BaseController;
import com.ipzoe.common.core.domain.AjaxResult;
import com.ipzoe.common.exception.CustomException;
import com.ipzoe.common.jwt.JwtTokenUtil;
import com.ipzoe.common.sms.SmsManager;
import com.ipzoe.file.domain.FileInfoDO;
import com.ipzoe.file.service.FileInfoDOService;
import com.ipzoe.mem.domain.Member;
import com.ipzoe.mem.domain.MemberRechargePackage;
import com.ipzoe.mem.model.MemberRechargePackageSnapshotDTO;
import com.ipzoe.mem.service.IMemberCardService;
import com.ipzoe.mem.service.IMemberRechargePackageService;
import com.ipzoe.mem.service.IMemberService;
import com.ipzoe.oms.domain.Order;
import com.ipzoe.oms.service.IOrderService;
import com.ipzoe.system.service.IRegionService;
import com.ipzoe.system.service.ISysDictDataService;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiImplicitParam;
import io.swagger.annotations.ApiImplicitParams;
import io.swagger.annotations.ApiOperation;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.validation.annotation.Validated;
import org.springframework.web.bind.annotation.*;
import org.springframework.web.multipart.MultipartFile;

import javax.servlet.http.HttpServletRequest;
import javax.validation.constraints.NotBlank;
import java.util.Date;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;

@RestController
@RequestMapping("api/v1/member")
@Api(tags = "会员业务")
@Slf4j
public class MemberController extends BaseController {

    @Autowired
    private IMemberService iMemberService;
    @Autowired(required = false)
    private CaptchaCodeManager captchaCodeManager;
    @Autowired(required = false)
    private SmsManager smsManager;
    @Autowired(required = false)
    private JwtTokenUtil jwtTokenUtil;
    @Autowired
    private IMemberRechargePackageService iMemberRechargePackageService;
    @Autowired
    private ISysDictDataService iSysDictDataService;
    @Autowired
    private IOrderService iOrderService;
    @Autowired
    private IActivityService iActivityService;
    @Autowired
    private IRegionService iRegionService;

    @Autowired
    private FileInfoDOService fileInfoDOService;
    @Autowired
    private IMemberCardService iMemberCardService;

    @PostMapping("captchaCode")
    @ApiOperation("获取验证码")
    @ApiImplicitParams({
            @ApiImplicitParam(name = "countryCode", value = "国家区号", required = true, dataType = "string"),
            @ApiImplicitParam(name = "phone", value = "手机号码", required = true, dataType = "string")
    })
    public AjaxResult getVerificationCode(@NotBlank(message = "国家区号不能为空") @RequestParam String countryCode,
            @NotBlank(message = "手机号码不能为空") @RequestParam String phone) {
        if("+86".equals(countryCode) && !Validator.isMobile(phone)){
            throw new CustomException(400,"请输入正确的手机号码");
        }
        CaptchaCode code = captchaCodeManager.create(phone);
        // 发送验证码
        if(!"+86".equals(countryCode)){
            phone = countryCode.replace("+","")+phone;
            smsManager.sendSms(phone, "SMS_209161374", code.getCode());
        }else{
            smsManager.sendSms(phone, "SMS_201500112", code.getCode());
        }

        return AjaxResult.success();
    }

    @PostMapping("hasRegistered")
    @ApiOperation("判断手机号是否注册")
    @ApiImplicitParams({
            @ApiImplicitParam(name = "countryCode", value = "国家区号", required = true, dataType = "string"),
            @ApiImplicitParam(name = "phone", value = "手机号码", required = true, dataType = "string")
    })
    public AjaxResult hasRegistered(@NotBlank(message = "国家区号不能为空") @RequestParam String countryCode,@NotBlank(message = "手机号码不能为空") @RequestParam String phone){
//        if(!Validator.isMobile(phone)){
//            throw new CustomException(400,"请输入正确的手机号码");
//        }
        if(!countryCode.contains("+")){
            countryCode = "+"+countryCode.trim();
        }
        if("+86".equals(countryCode) && !Validator.isMobile(phone)){
            throw new CustomException(400,"请输入正确的手机号码");
        }
        LambdaQueryWrapper<Member> memberLqw = new QueryWrapper<Member>().lambda()
                .eq(Member::getMobile1Code, countryCode)
                .eq(Member::getMobile1, phone);
        Member member = iMemberService.getOne(memberLqw);
        return AjaxResult.success(member != null);
    }

    @PostMapping("login")
    @ApiOperation("用户登录")
    public AjaxResult login(@RequestBody @Validated LoginDTO dto) {

        String mobile = dto.getMobile();
        String countryCode = dto.getCountryCode();
//        if(!"+86".equals(countryCode)){
//            mobile = countryCode.replace("+","")+mobile;
//        }
        if("+86".equals(countryCode) && !Validator.isMobile(mobile)){
            throw new CustomException(400,"请输入正确的手机号码");
        }
        // 验证短信验证码
        if (!"6666".equals(dto.getCaptchaCode())) {
            captchaCodeManager.validate(dto.getMobile(), dto.getCaptchaCode());
        }

        Date today =new Date();
        LambdaQueryWrapper<Member> memberLqw = new QueryWrapper<Member>().lambda()
                .eq(Member::getMobile1Code, countryCode)
                .eq(Member::getMobile1, mobile);
        Member member = iMemberService.getOne(memberLqw);
        if (member == null) {
            member = new Member();
            member.setMemberLevel(1);
            member.setUsername(dto.getMobile());
            member.setMobile1Code(dto.getCountryCode());
            member.setMobile1(dto.getMobile());
            if(dto.getBirthday() != null){
                member.setBirthday(dto.getBirthday());
            }
            if(dto.getSex() != null){
                member.setSex(dto.getSex());
            }
            if(StrUtil.isNotEmpty(dto.getOpenId())){
                member.setWeixinOpenid(dto.getOpenId());
            }
            if(StrUtil.isNotEmpty(dto.getNickname())){
                member.setNickname(dto.getNickname());
            }
            if(StrUtil.isNotEmpty(dto.getAvatar())){
                member.setAvatar(dto.getAvatar());
            }
            member.setStatus(1);
            member.setLastLoginTime(today);
            member.setRegisterTime(today);
            iMemberService.save(member);
        }else{
            if(StrUtil.isNotEmpty(dto.getOpenId())){
                member.setWeixinOpenid(dto.getOpenId());
            }
//            if(StrUtil.isNotEmpty(dto.getNickname())){
////                member.setNickname(dto.getNickname());
////            }
//            if(StrUtil.isNotEmpty(dto.getAvatar())){
//                member.setAvatar(dto.getAvatar());
//            }
            if(dto.getBirthday() != null){
                member.setBirthday(dto.getBirthday());
            }
            if(dto.getSex() != null){
                member.setSex(dto.getSex());
            }
            member.setLastLoginTime(today);
            member.setUpdateBy("用户");
            iMemberService.updateById(member);
        }

        Map<String, Object> claims = Maps.newHashMap();
        claims.put("memberId", member.getId());
        claims.put("openId", member.getWeixinOpenid());

        String token = jwtTokenUtil.generateToken(String.valueOf(member.getId()), claims);
        LoginResponseDTO result = new LoginResponseDTO();
        result.setToken(token);
        result.setMemberId(member.getId());
        result.setMemberStatus(member.getMemberStatus());

        return AjaxResult.success(result);
    }

    /**
     * 查询用户，会员详情
     */
    @Login
    @GetMapping("/info")
    @ApiOperation("会员信息")
    public AjaxResult detail(HttpServletRequest request)
    {
        Member member = (Member) request.getAttribute(AppConstants.REQUEST_ATTRIBUTE_KEY_MEMBER);

        return AjaxResult.success(member);
    }

    @Login
    @GetMapping("/rechargePackage/list")
    @ApiOperation("会员充值套餐列表信息")
    public AjaxResult rechargePackageList(){
        LambdaQueryWrapper<MemberRechargePackage> rechargePackageLqw = new LambdaQueryWrapper<>();
        rechargePackageLqw.apply("date_format(expiry_day,'%y%m%d') > date_format({0},'%y%m%d')", DateUtil.today());
        List<MemberRechargePackage> rechargePackageList = iMemberRechargePackageService.list(rechargePackageLqw);
        List<MemberRechargePackageDTO> rechargePackageDTOList = MemberRechargePackageConvert.INSTANCE.convert(rechargePackageList);
        rechargePackageDTOList.forEach(t->{
            t.setEffectiveUnitStr(iSysDictDataService.selectDictLabel("mem_recharge_package_unit", String.valueOf(t.getEffectiveUnit())));
        });
        return AjaxResult.success(rechargePackageDTOList);
    }

    @Login
    @ApiOperation("卡券兑换")
    @PostMapping("/exchange")
    @ApiImplicitParam(name = "cardNum", value = "卡券号码", required = true)
    public AjaxResult exchange(String cardNum, HttpServletRequest request){

        if(StrUtil.isBlank(cardNum)){
            throw new CustomException(400,"缺少卡券号码");
        }

        Member member = (Member) request.getAttribute(AppConstants.REQUEST_ATTRIBUTE_KEY_MEMBER);
        iOrderService.exchangeMemberCard(cardNum, member.getId());

        return AjaxResult.success();
    }

    @Login
    @ApiOperation("充值记录")
    @PostMapping("/order/list")
    public AjaxResult orderList(HttpServletRequest request){

        Member member = (Member) request.getAttribute(AppConstants.REQUEST_ATTRIBUTE_KEY_MEMBER);

        LambdaQueryWrapper<Order> orderLqw = new LambdaQueryWrapper<>();
        orderLqw.eq(Order::getMemberId, member.getId());
        List<Order> orderList = iOrderService.list(orderLqw);
        List<OrderDTO> orderVOList = OrderConvert.INSTANCE.convert(orderList);
        if(CollUtil.isNotEmpty(orderVOList)){
            Map<Long, Order> orderIdMap = orderList.parallelStream().collect(Collectors.toMap(Order::getId, t->t));
            for (OrderDTO orderDTO : orderVOList) {
                orderDTO.setOrderTypeStr(iSysDictDataService.selectDictLabel("oms_order_type", String.valueOf(orderDTO.getOrderType())));
                if(orderDTO.getCardId() != null){
                    orderDTO.setMemberCard(iMemberCardService.getById(orderDTO.getCardId()));
                }
                if(orderDTO.getPackageId() != null){
                    orderDTO.setRechargePackage(MemberRechargePackageConvert.INSTANCE.convert(iMemberRechargePackageService.getById(orderDTO.getPackageId())));
                    if(orderDTO.getRechargePackage() == null && StrUtil.isNotEmpty(orderIdMap.get(orderDTO.getId()).getPackageSnapshot())){
                        orderDTO.setRechargePackage(JSON.parseObject(orderIdMap.get(orderDTO.getId()).getPackageSnapshot(), MemberRechargePackageSnapshotDTO.class));
                    }
                }
            }
        }

        return AjaxResult.success(orderVOList);
    }

    @Login
    @ApiOperation("报过名的活动")
    @GetMapping("/signedActivityList")
    @ApiImplicitParam(name = "status", value = "状态：1,全部；2，待参加；3，已结束", allowableValues = "1,2,3",required = false, defaultValue = "1")
    public AjaxResult signedActivityList(HttpServletRequest request, @RequestParam(defaultValue = "1") Integer status){

        Member member = (Member) request.getAttribute(AppConstants.REQUEST_ATTRIBUTE_KEY_MEMBER);

        Integer querySignStatus = null;
        Integer queryActivityStatus = null;
        switch (status){
            case 2:
                querySignStatus = 0;
                break;
            case 3:
                queryActivityStatus = 2;
                break;
            case 1:
            default:
                break;
        }

        List<SignedActivityBO> signedActivityBOList = iActivityService.listSignedActivity(member.getId(), querySignStatus, queryActivityStatus);
        List<SignedActivityDTO> signedActivityDTOList = ActivityConvert.INSTANCE.convertSignedList(signedActivityBOList);
        signedActivityDTOList.forEach(r->{
            r.setCity(iRegionService.getById(r.getCityCode()));
            r.setPermissionDictLabel(iSysDictDataService.selectDictLabel("act_active_permission", String.valueOf(r.getPermission())));
            r.setStatusDictLabel(iSysDictDataService.selectDictLabel("act_active_status", String.valueOf(r.getStatus())));
        });

        return AjaxResult.success(signedActivityDTOList);
    }

    @Login
    @PostMapping("/changeMobile")
    @ApiOperation("修改手机号")
    @ApiImplicitParams({
            @ApiImplicitParam(name = "countryCode", value = "新的手机号码国家区号", required = true),
            @ApiImplicitParam(name = "mobile", value = "新的手机号码", required = true),
            @ApiImplicitParam(name = "captchaCode", value = "验证码", required = true)
    })
    public AjaxResult changeMobile(@RequestParam String countryCode,@RequestParam String mobile, @RequestParam String captchaCode, HttpServletRequest request)
    {
        if(!countryCode.contains("+")){
            countryCode = "+"+countryCode.trim();
        }
        if("+86".equals(countryCode) && !Validator.isMobile(mobile)){
            throw new CustomException(400, "请输入正确的手机号码");
        }
        if(StrUtil.isBlank(captchaCode)){
            throw new CustomException(400, "请输入验证码");
        }
//        if(!"+86".equals(countryCode)){
//            mobile = countryCode.replace("+","")+mobile;
//        }

        if (!"6666".equals(mobile)) {
            captchaCodeManager.validate(mobile, captchaCode);
        }

        Member member = (Member) request.getAttribute(AppConstants.REQUEST_ATTRIBUTE_KEY_MEMBER);
        if(mobile.equals(member.getMobile1())){
            throw new CustomException(400, "请勿重复绑定手机号");
        }

        LambdaQueryWrapper<Member> memberLqw = new QueryWrapper<Member>().lambda()
                .eq(Member::getMobile1Code, countryCode)
                .eq(Member::getMobile1, mobile);
        if(iMemberService.count(memberLqw)>0){
            throw new CustomException(400, "该手机号已关联其他用户");
        }

        member.setUpdateBy("用户");
        if(member.getMobile1().equals(member.getUsername())){
            member.setUsername(mobile);
        }
        member.setMobile1Code(countryCode);
        member.setMobile1(mobile);
        iMemberService.updateById(member);

        return AjaxResult.success();
    }

    @Login
    @PostMapping("/updateAvatar")
    @ApiOperation("修改个人信息")
    @ApiImplicitParam(name = "file", value = "头像图片", dataType = "file")
    public AjaxResult updateAvatar(MultipartFile file,HttpServletRequest request){

        Member member = (Member) request.getAttribute(AppConstants.REQUEST_ATTRIBUTE_KEY_MEMBER);

        if (file == null || file.isEmpty()){
            throw new CustomException(400,"您上传的文件为空");
        }

        FileInfoDO uploadFile = fileInfoDOService.upload(file, "/member/avatar");
        member.setAvatar(uploadFile.getUrl());
        member.setUpdateBy("用户");
        iMemberService.updateById(member);

        AjaxResult ajaxResult = AjaxResult.success();
        ajaxResult.put("url", uploadFile.getUrl());
        return ajaxResult;
    }

    @Login
    @PostMapping("/update")
    @ApiOperation("修改个人信息")
    public AjaxResult update(@RequestBody  MemberUpdateRequestDTO dto,
                             HttpServletRequest request) {

        Member member = (Member) request.getAttribute(AppConstants.REQUEST_ATTRIBUTE_KEY_MEMBER);

        if(StrUtil.isNotEmpty(dto.getNickname())){
            member.setNickname(dto.getNickname());
        }
        if(dto.getSex() != null && (dto.getSex() == 0 || dto.getSex() == 1)){
            member.setSex(dto.getSex());
        }
        if(dto.getBirthday() != null){
            member.setBirthday(dto.getBirthday());
        }
        if(dto.getDiveLevel() != null){
            member.setDiveLevel(dto.getDiveLevel());
        }
        if(dto.getDiveSystem() != null){
            member.setDiveSystem(dto.getDiveSystem());
        }
        member.setUpdateBy("用户");
        iMemberService.updateById(member);

        return AjaxResult.success();
    }

}
